<?php

namespace App\Models;

use App\Jobs\MakePlayerPoster;
use App\Models\Traits\BelongsToApplication;
use App\Models\Traits\HasCovers;
use App\Models\Traits\HasEasyStatus;
use App\Models\Traits\HasLikes;
use App\Models\Traits\PlayerAction;
use Exception;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\DB;
use Vinkla\Hashids\Facades\Hashids;

class Player extends Model
{
    use BelongsToApplication,
        HasEasyStatus,
        HasCovers,
        HasLikes,
        PlayerAction,
        SoftDeletes;

    protected static function boot(): void
    {
        parent::boot();

        self::creating(function (Player $player) {
            if (!$player->chapter) {
                throw new Exception('缺少选手场次');
            }

            $player->season_id = $player->chapter->season_id;
        });

        self::created(function (Player $player) {
            $slug = Hashids::connection('player')->encode($player->application_id, $player->id, rand(1, 999));
            $player->update(['slug' => $slug]);
        });
    }

    public function getRouteKeyName(): string
    {
        return 'slug';
    }

    public function guides(): HasMany
    {
        return $this->hasMany(Guide::class);
    }

    public function season(): BelongsTo
    {
        return $this->belongsTo(Season::class);
    }

    public function chapter(): BelongsTo
    {
        return $this->belongsTo(Chapter::class);
    }

    public function getRankAttribute(): string
    {
        try {
            $SQL = 'SELECT u.rowNo FROM (SELECT id,(@rowNum:=@rowNum+1) AS rowNo FROM players, (SELECT (@rowNum :=0)) b WHERE chapter_id=:chapter AND status = 1 AND deleted_at IS NULL ORDER BY players.polls DESC) u WHERE u.id=:id';
            $res = DB::select($SQL, ['chapter' => $this->chapter_id, 'id' => $this->id]);

            return $res[0]->rowNo;
        } catch (Exception $exception) {
            return '[出局]';
        }
    }

    public function getBehindFirstAttribute(): int
    {
        if ($this->rank == 1) {
            return 0;
        } else {
            $first = $this->chapter->players()->orderByDesc('polls')->value('polls');

            return $first - $this->polls;
        }
    }

    /**
     * Notes   : 获取距离上一名的差距票数
     *
     * @Date   : 2024/7/23 下午4:04
     * @Author : <Jason.C>
     * @return int
     */
    public function getBehindLastAttribute(): int
    {
        if ($this->rank == 1) {
            return 0;
        } else {
            $last = $this->chapter->players()->where('polls', '>', $this->polls)->orderBy('polls')->value('polls');

            return $last - $this->polls;
        }
    }

    public function updatePoster(): void
    {
        $poster = $this->posters()->create();

        MakePlayerPoster::dispatch($this, $poster);
    }

    public function posters(): HasMany
    {
        return $this->hasMany(Poster::class);
    }

    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'user_player')
            ->withPivot('guardian');
    }

    public function getPlayerUrl(): ?string
    {
        return $this->chapter->getPlayerDomain()?->makeSubDomain($this->slug);
    }

    public function getRankUrl(): ?string
    {
        return $this->chapter->getRankDomain()?->makeSubDomain($this->slug);
    }
}
